In this part we will look at a few extensions of the model and the effect of different world topologies.
using Random
include("SimpleAgentEvents/src/SimpleAgentEvents.jl")
using .SimpleAgentEvents
using .SimpleAgentEvents.Scheduler
Agents can now be immune and dead as well.
@enum Status susceptible infected immune dead
mutable struct Person
status :: Status
contacts :: Vector{Person}
x :: Float64
y :: Float64
end
Person(x, y) = Person(susceptible, [], x, y)
Person(state, x, y) = Person(state, [], x, y)
mutable struct Simulation
scheduler :: PQScheduler{Float64}
# infection rate
inf :: Float64
# recovery rate
rec :: Float64
# new parameters:
# immunisation rate
imm :: Float64
# mortality rate
mort :: Float64
pop :: Vector{Person}
end
scheduler(sim :: Simulation) = sim.scheduler
Simulation(i, r, u, m) = Simulation(PQScheduler{Float64}(), i, r, u, m, [])
For the first extension I let infected agents become immune instead of susceptible again with a certain rate.
@processes SIR sim person::Person begin
@poisson(sim.inf * count(p -> p.status == infected, person.contacts)) ~
person.status == susceptible =>
begin
person.status = infected
[person; person.contacts]
end
@poisson(sim.rec) ~
person.status == infected =>
begin
person.status = susceptible
[person; person.contacts]
end
# now agents become immune after having been infected
@poisson(sim.imm) ~
person.status == infected =>
begin
person.status = immune
# an immune agent effectively becomes inactive, so
# only the contacts are returned to the scheduler
person.contacts
end
end
We are including a second file here. It contains the visualisation code from the previous notebook as a function.
include("setup_world.jl")
include("draw.jl")
sim = Simulation(0.5, 0.1, 0.2, 0)
sim.pop = setup_grid(50, 50)
sim.pop[1].status = infected
for person in sim.pop
spawn_SIR(person, sim)
end
Random.seed!(42);
for t in 1:10
upto!(sim.scheduler, time_now(sim.scheduler) + 1.0)
println(time_now(sim.scheduler), ", ",
count(p -> p.status == infected, sim.pop), ", ",
count(p -> p.status == susceptible, sim.pop))
end
For convenience I have put the visualisation code into a function.
draw_sim(sim)
Now we also assume that the infected people can die.
@processes SIRm sim person::Person begin
@poisson(sim.inf * count(p -> p.status == infected, person.contacts)) ~
person.status == susceptible =>
begin
person.status = infected
[person; person.contacts]
end
@poisson(sim.rec) ~
person.status == infected =>
begin
person.status = susceptible
[person; person.contacts]
end
@poisson(sim.imm) ~
person.status == infected =>
begin
person.status = immune
person.contacts
end
# mortality
@poisson(sim.mort) ~
person.status == infected =>
begin
person.status = dead
person.contacts
end
end
sim_m = Simulation(0.5, 0.1, 0.2, 0.1)
sim_m.pop = setup_grid(50, 50)
sim_m.pop[1].status = infected
for person in sim_m.pop
spawn_SIRm(person, sim_m)
end
Random.seed!(42);
for t in 1:10
upto!(sim_m.scheduler, time_now(sim_m.scheduler) + 1.0)
println(time_now(sim_m.scheduler), ", ",
count(p -> p.status == infected, sim_m.pop), ", ",
count(p -> p.status == susceptible, sim_m.pop))
end
draw_sim(sim_m)
Now, instead of a regular grid, we place the agent on an irregular graph. The algorithm is called a random geometric graph and was used as one of the first (very simple) models of transport networks.
The function is declared as follows:
function setup_geograph(n = 2500, near = 0.05, rand_cont = 0)
with number of nodes n, threshold to connect nodes near (don't set this much higher or it might crash your browser) and number of additional random connections rand_cont (the latter is not part of the original RGG).
sim_m2 = Simulation(0.2, 0.01, 0.06, 0.00143)
sim_m2.pop = setup_geograph(2500, 0.025, 50)
sim_m2.pop[1].status = infected
for person in sim_m2.pop
spawn_SIRm(person, sim_m2)
end
Random.seed!(42);
for t in 1:7
upto!(sim_m2.scheduler, time_now(sim_m2.scheduler) + 1.0)
println(time_now(sim_m2.scheduler), ", ",
count(p -> p.status == infected, sim_m.pop), ", ",
count(p -> p.status == susceptible, sim_m.pop))
end
draw_sim(sim_m2)
rand_cont) in geo graph?near in geo graph?